/*
 * ck156_cmd.c
 *
 *  Created on: Aug 22, 2024
 *      Author: 31652
 */

#include "ck156_cmd.h"

#define __ck156_card_selected 1
#define __ck156_card_unselect 1

void OnPacket(uint8_t* packet, uint8_t dataLen);


uint32_t __cmd_wrapper(uint8_t cmd, uint8_t* data, uint8_t dataLen, uint8_t* packetBuffer);
void _onTag(uint8_t* uid);
void _cmd_inventory_resp(uint8_t* packet, uint8_t dataLen);
void _cmd_read_block_resp(uint8_t* packet, uint8_t dataLen);
void _cmd_read_blocks_resp(uint8_t* packet, uint8_t dataLen);
void _cmd_write_block_resp(uint8_t* packet, uint8_t dataLen);
void _cmd_write_blocks_resp(uint8_t* packet, uint8_t dataLen);
void _cmd_lock_resp(uint8_t* packet, uint8_t dataLen);

OnTag _tagListener;

uint8_t cmd;
uint8_t _ck156_uid[8];
uint8_t _ck156_card_select_status;
uint8_t __packetCmdBuffer[128];
uint8_t dataLen;

uint8_t __blockFrom;
uint8_t __blockLen;

void SelectTag(uint8_t* uid) {
	memcpy(_ck156_uid, uid, 8);
	_ck156_card_select_status = __ck156_card_selected;
}

void GetSelectedTag(uint8_t* uid) {
	memcpy(uid, _ck156_uid, 8);
}

void UnSelectedTag() {
	_ck156_card_select_status = __ck156_card_unselect;
}


void Ck156_Read_Block(uint8_t fromBlock, ReadBlockCallback cb) {
	__blockFrom = fromBlock;
	__blockLen = 1;
	_15693_set_read_block_listener(cb);
	uint8_t* packet = GetPacketBuffer();
	__packetCmdBuffer[0] = fromBlock;
	__cmd_wrapper(_Cmd_Read_Block, __packetCmdBuffer, 1, packet);
}

void Ck156_Reads_Block(uint8_t fromBlock, uint8_t blockQty, ReadBlocksCallback cb) {
	_15693_set_read_blocks_listener(cb);
	__blockFrom = fromBlock;
	__blockLen = blockQty;
	// TODO
}

void Ck156_Write_Block(uint8_t block, uint8_t* payload, WriteBlockCallback cb) {
	_15693_set_write_block_listener(cb);
	__blockFrom = block;
	__blockLen = 1;
	__packetCmdBuffer[0] = __blockFrom;
	memcpy(__packetCmdBuffer+1, payload, 4);
	__cmd_wrapper(_Cmd_Write_Block, __packetCmdBuffer, 5, payload);
}
void Ck156_Write_Blocks(uint8_t block, uint8_t blocks, uint8_t* payload, WriteBlocksCallback cb) {
	_15693_set_write_blocks_listener(cb);
	__blockFrom = block;
	__blockLen = blocks;
	__packetCmdBuffer[0] = __blockFrom;
	memcpy(__packetCmdBuffer+1, payload, __blockLen*4);
	__cmd_wrapper(_Cmd_Write_Blocks, __packetCmdBuffer, 1+__blockLen*4, payload);
}

void Ck156_Lock_Block(uint8_t block, LockBlockCallback cb) {
	_15693_set_lock_block_listener(cb);
	// TODO
}

void OnPacket(uint8_t* packet, uint8_t dataLen) {
	// check sum TODO
	cmd = packet[2];

	switch(cmd) {
	case _Cmd_Inv: // inventory -->UID
		_cmd_inventory_resp(packet, dataLen);
		break;
	case _Cmd_Read_Block: // one block
		_cmd_read_block_resp(packet, dataLen);
		break;
	case _Cmd_Read_Blocks: // read blocks (1-14)
		_cmd_read_blocks_resp(packet, dataLen);
		break;
	case _Cmd_Write_Block: // one block
		_cmd_write_block_resp(packet, dataLen);
		break;
	case _Cmd_Write_Blocks: // write blocks (1-14)
		_cmd_write_blocks_resp(packet, dataLen);
		break;
	case _Cmd_Lock: // lock block
		_cmd_lock_resp(packet, dataLen);
		break;
	}
}

void SetTagListener(OnTag listener) {
	_tagListener = listener;
}

void RemoveTagListener() {
	_tagListener = NULL;
}

void _onTag(uint8_t* uid) {
	if (_tagListener == NULL) {
		return;
	}
	_tagListener(uid);
}

void _cmd_inventory_resp(uint8_t* packet, uint8_t dataLen) {

//	printf("_cmd_inventory_resp\n");
	if (dataLen > 6) {
		printf("--tag in.\n");
		memcpy(_ck156_uid, packet+4, dataLen);
		_onTag(_ck156_uid);
	} else {
		printf("--tag leave.\n");
	}
}
void _cmd_read_block_resp(uint8_t* packet, uint8_t dataLen) {
	if (dataLen == 1) {
		_15693_on_read_block_resp(__blockFrom, __packetCmdBuffer, packet[4]);
		return;
	}
	memcpy(__packetCmdBuffer, packet+4, 4);
	_15693_on_read_block_resp(__blockFrom, __packetCmdBuffer, 0x00);
}
void _cmd_read_blocks_resp(uint8_t* packet, uint8_t dataLen) {
	if (dataLen == 1) {
		_15693_on_read_blocks_resp(__blockFrom, __blockLen, __packetCmdBuffer, packet[4]);
		return;
	}
	memcpy(__packetCmdBuffer, packet+4, dataLen);
	_15693_on_read_blocks_resp(__blockFrom, __blockLen, __packetCmdBuffer, 0x00);
}
void _cmd_write_block_resp(uint8_t* packet, uint8_t dataLen) {
//	printf("_cmd_write_block_resp\n");
	if (dataLen != 1) {
		return;
	}
	_15693_on_write_block_resp(__blockFrom, packet[4]);
}
void _cmd_write_blocks_resp(uint8_t* packet, uint8_t dataLen) {
//	printf("_cmd_write_blocks_resp\n");
	if (dataLen != 1) {
		return;
	}
	_15693_on_write_blocks_resp(__blockFrom, __blockLen, packet[4]);
}
void _cmd_lock_resp(uint8_t* packet, uint8_t dataLen) {
	printf("_cmd_lock_resp\n");
	// TODO
}

uint32_t __cmd_wrapper(uint8_t cmd, uint8_t* data, uint8_t dataLen, uint8_t* packetBuffer) {
	packetBuffer[0] = PacketHead;
	packetBuffer[1] = 0x00; // Default ADDR
	packetBuffer[2] = cmd;
	packetBuffer[3] = dataLen;
	memcpy(packetBuffer+4, data, dataLen);
	packetBuffer[4+dataLen] = 0x00; // TODO BCC
	packetBuffer[4+dataLen+1] = PacketTail;

	SendTxData(packetBuffer, dataLen+6);
	return dataLen+6;
}

